package com.taoyusen.common.base.impl;

import java.io.Serializable;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.SQLQuery;
import org.hibernate.Session;
import org.springframework.dao.DataAccessException;
import org.springframework.orm.hibernate3.HibernateCallback;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;

import com.taoyusen.common.base.IBaseDAO;
import common.Logger;

public abstract class BaseDAOImpl<T,ID extends Serializable> extends HibernateDaoSupport 
	implements IBaseDAO<T,ID> 
{

	protected abstract  Class<T> getPOJOClass();

	private  Logger logger = Logger.getLogger(this.getPOJOClass());
	
	public boolean delete(T object) 
	{
		boolean success = false;
		
		try 
		{
			this.getHibernateTemplate().delete(object);
			success= true;
		} catch (DataAccessException e)
		{
			e.printStackTrace();
			logger.info("删除"+this.getPOJOClass().getName()+"实例对象失败！");
		}
		
		return success;
	}

	public boolean deleteByIds(final ID[] ids) 
	{
		boolean success = false;
		final String deletehql ="delete from "+this.getPOJOClass().getName()+" where id in(:id)";
		
		try 
		{
			this.getHibernateTemplate().execute(new HibernateCallback()
			{
				public Object doInHibernate(Session session) throws HibernateException, SQLException
				{
					Query query = session.createQuery(deletehql);
					query.setParameterList("id", ids);
					query.executeUpdate();
					return null;
				}
			});
		} catch (DataAccessException e)
		{
			e.printStackTrace();
			logger.info("删除ID为"+ids+"实例对象");
		}
		
		return success;
	}

	public Query createQuery(final String hql)
	{
		try 
		{
			return (Query) this.getHibernateTemplate().execute(new HibernateCallback()
			{
				public Object doInHibernate(Session session)throws HibernateException, SQLException 
				{
						return session.createQuery(hql);
				}
				
			});
		} 
		catch (DataAccessException e) 
		{
			e.printStackTrace();
			logger.info("HQL语句为"+hql+"查询失败！");
		}
		return null;
	}
	
	
	public SQLQuery createSQLQueryByEntity(final String sql)
	{
		try 
		{
			final Class<T> pojoClass = this.getPOJOClass();
			
			return (SQLQuery) this.getHibernateTemplate().execute(new HibernateCallback()
			{
				public Object doInHibernate(Session session)throws HibernateException, SQLException 
				{	
					return session.createSQLQuery(sql).addEntity(sql, pojoClass);
					
				}
			});
		} 
		catch (DataAccessException e) 
		{
			e.printStackTrace();
			logger.info("HQL语句为"+sql+"查询失败！");
		}
		return null;
	}
	
	public List<T> getAllObject() 
	{
		return getHibernateTemplate().loadAll(this.getPOJOClass());
	}

	public T getObjectById(ID id) 
	{
		return (T)getHibernateTemplate().get(this.getPOJOClass(), id);
	}

	public boolean sava(T object) 
	{
		boolean success = false;
		
		try
		{
			getHibernateTemplate().save(object);
		} catch (DataAccessException e) 
		{
			e.printStackTrace();
			System.out.println("保存数据失败！");
		}
		
		return success;
	}

	public boolean update(T object) 
	{
		boolean success = false;
		
		try
		{
			getHibernateTemplate().update(object);
		} catch (DataAccessException e) 
		{
			e.printStackTrace();
			System.out.println("修改数据失败！");
		}
		
		return success;
	}

	/**
	 * 利用hibernate回调函数写的执行查询原生SQL的函数
	 * @param sql
	 * @return
	 */
	public List executeSqlQuery(String sql)
	{
		Session session = this.getSession();
		try {
			System.out.println(sql);
			Connection connection =  session.connection();
			PreparedStatement statement = connection.prepareStatement(sql);
			ResultSet resultSet = statement.executeQuery();
			List resultList = this.convertResultSetToList(resultSet);
			
			resultSet.close();
			statement.close();
			
			return resultList;
		} 
		catch (HibernateException e) 
		{
			e.printStackTrace();
		} 
		catch (SQLException e) 
		{
			e.printStackTrace();
		}
		catch (Exception e) 
		{
			e.printStackTrace();
		}
		return null;
	}
	
	
	public static List convertResultSetToList(ResultSet rs) throws Exception {
		ResultSetMetaData rsmd = rs.getMetaData();
		int columnNumber = rsmd.getColumnCount(); // 得到表列
		ArrayList ret = null;
		if (rs != null) {
			ret = new ArrayList();
			while (rs.next()) {
				Object[] obj = new Object[columnNumber];
				for (int i = 1; i <= columnNumber; i++) {
					obj[i - 1] = rs.getObject(i);
				}
				ret.add(obj);
			}
		}
		return ret;
	}
	
	
}
